package org.example.ymcc.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import org.aspectj.weaver.ast.Var;
import org.example.ymcc.constant.RConst;
import org.example.ymcc.domain.*;
import org.example.ymcc.dto.CourseAddDto;
import org.example.ymcc.feignclient.ESFeignClient;
import org.example.ymcc.feignclient.MediaFeignClient;
import org.example.ymcc.mapper.*;
import org.example.ymcc.producer.CourserOnlineProducer;
import org.example.ymcc.result.JsonResult;
import org.example.ymcc.service.ICourseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zcj
 * @since 2024-06-11
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    @Autowired
    private CourseResourceMapper courseResourceMapper;
    @Autowired
    private CourseSummaryMapper courseSummaryMapper;
    @Autowired
    private CourseDetailMapper courseDetailMapper;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private CourseCollectMapper courseCollectMapper;
    @Autowired
    private ESFeignClient esFeignClient;
    @Autowired
    private CourserOnlineProducer producer;
    @Autowired
    private CourseChapterMapper courseChapterMapper;
    @Autowired
    private MediaFeignClient mediaFeignClient;

    @Transactional
    @Override
    public boolean removeById(Serializable id) {
        courseMarketMapper.deleteById(id);
        courseResourceMapper.deleteById(id);
        courseSummaryMapper.deleteById(id);
        courseDetailMapper.deleteById(id);
        courseMapper.deleteTeacherByCourseId(Long.valueOf(id.toString()));
        return super.removeById(id);
    }
    @Transactional
    @Override
    public void save(CourseAddDto course, JSONObject currentLogin) {
        buildCourse(course, currentLogin);
        super.save(course.getCourse());
        Long courseId = course.getCourse().getId();
        CourseDetail courseDetail = course.getCourseDetail();
        courseDetail.setId(courseId);
        CourseMarket courseMarket = course.getCourseMarket();
        courseMarket.setId(courseId);
        //假设前端默认传的一个
        CourseResource courseResource = course.getCourseResource();
        courseResource.setCourseId(courseId);
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(courseId);
        courseSummary.setCommentCount(RConst.Num.INT_0);
        courseSummary.setSaleCount(RConst.Num.INT_0);
        courseSummary.setViewCount(RConst.Num.INT_0);
        courseMarketMapper.insert(courseMarket);
        courseDetailMapper.insert(courseDetail);
        courseResourceMapper.insert(courseResource);
        courseSummaryMapper.insert(courseSummary);
        courseMapper.saveCourseTeacher(courseId,course.getTeacharIds());
    }
    @Override
    public JsonResult getDetail(Long courseId) {
        //查询
        CourseMarket courseMarket = courseMarketMapper.selectById(courseId);
        List<CourseResource> courseResources = courseResourceMapper.selectList(
                new LambdaQueryWrapper<CourseResource>().eq(CourseResource::getCourseId, courseId));
        CourseSummary courseSummary = courseSummaryMapper.selectById(courseId);
        CourseDetail courseDetail = courseDetailMapper.selectById(courseId);
        //查老师的id
        List<Long> tId = courseMapper.selectTeacherByCourseId(courseId);
        Course course = courseMapper.selectById(courseId);
        CourseType type = courseTypeMapper.selectById(course.getCourseTypeId());
        Map<String,Object> result = new HashMap<>(RConst.Num.INT_5);
        result.put("courseMarket",courseMarket);
        result.put("courseResources",courseResources);
        result.put("courseSummary",courseSummary);
        result.put("courseDetail",courseDetail);
        result.put("tId",tId);
        result.put("courseType",type);
        return JsonResult.success().setData(result);
    }
    /**
     * 做什么事情
     * @param ids
     * @return
     */
    @Override
    public JsonResult onLineCourse(List<Long> ids) {
        //修改状态
        Course course = new Course();
        course.setStatus(RConst.Num.INT_1);
        course.setOnlineTime(new Date());
        //已经上线会出现重复上线的情况怎么解决
        courseMapper.update(course,new LambdaQueryWrapper<Course>()
                .eq(Course::getStatus,RConst.Num.INT_0)
                .in(Course::getId,ids));
        List<CourseDoc> docs = getCourseDocs(ids);
        //远程调用 进行发布es
        esFeignClient.batchSave(docs);
        //使用mq去发送一个短信或邮箱 或者 站内信
        producer.sendMessage(ids);
        return JsonResult.success();
    }
    /**
     * 发送远程调用 es 查询详情数据
     * @param courseId
     * @return
     */
    @Override
    public JsonResult getDetailData(Long courseId) {
        JsonResult result = esFeignClient.getCourseDoc(courseId);
        CourseDoc courseDoc = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), CourseDoc.class);
        Course course = new Course();
        BeanUtils.copyProperties(courseDoc,course);// BeanUtils.copyProperties  类型和字段名必须相同
        CourseMarket courseMarket = new CourseMarket();
        BeanUtils.copyProperties(courseDoc,courseMarket);
        courseMarket.setPrice(new BigDecimal(courseDoc.getPrice()));
        courseMarket.setPriceOld(new BigDecimal(courseDoc.getPriceOld()));
        CourseDetail courseDetail = new CourseDetail();
        BeanUtils.copyProperties(courseDoc,courseDetail);
        CourseSummary courseSummary = new CourseSummary();
        BeanUtils.copyProperties(courseDoc,courseSummary);
        //查询老师
        List<Teacher> teachers = teacherMapper.selectTeacherByCourseId(courseId);
        //查询章节
        List<CourseChapter> courseChapters = courseChapterMapper.selectList(new LambdaQueryWrapper<CourseChapter>().eq(CourseChapter::getCourseId, courseId));
        //查询视频
        JsonResult video = mediaFeignClient.getVideo(courseId);
        List<MediaFile> mediaFiles = JSONObject.parseArray(JSONObject.toJSONString(video.getData()), MediaFile.class);
        courseChapters.forEach(chapters->{
            for (MediaFile mediaFile : mediaFiles) {
                if(chapters.getId().equals(mediaFile.getChapterId())){
                    chapters.getMediaFileList().add(mediaFile);
                }
            }
        });
        HashMap<String, Object> map = new HashMap<>();
        map.put("course",course);
        map.put("courseMarket",courseMarket);
        map.put("courseDetail",courseDetail);
        map.put("courseSummary",courseSummary);
        map.put("teachers",teachers);
        map.put("courseChapters",courseChapters);
        return JsonResult.success().setData(map);
    }
    @Override
    public JsonResult info(List<Long> courseIds) {
        List<CourseDoc> docList = new ArrayList<>(courseIds.size());
        for (Long courseId : courseIds) {
            JsonResult result = esFeignClient.getCourseDoc(courseId);
            CourseDoc courseDoc = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), CourseDoc.class);
            docList.add(courseDoc);
        }
        return JsonResult.success().setData(docList);
    }
    private List<CourseDoc> getCourseDocs(List<Long> ids) {
        //添加到es里面  自己构建courseDoc数据
        List<CourseDoc> docs = new ArrayList<>(ids.size());
        List<Course> courses = super.listByIds(ids);
        courses.forEach(item ->{
            CourseDoc courseDoc = new CourseDoc();
            BeanUtils.copyProperties(item,courseDoc);
            CourseType type = courseTypeMapper.selectById(item.getCourseTypeId());
            if(type != null){
                courseDoc.setCourseTypeName(type.getName());
            }
            courseDoc.setStartTime(item.getStartTime().getTime());
            courseDoc.setEndTime(item.getEndTime().getTime());
            courseDoc.setOnlineTime(item.getOnlineTime().getTime());
            CourseDetail courseDetail = courseDetailMapper.selectById(item.getId());
            BeanUtils.copyProperties(Optional.ofNullable(courseDetail).orElse(new CourseDetail()),courseDoc);
            CourseMarket courseMarket = courseMarketMapper.selectById(item.getId());
            BeanUtils.copyProperties(Optional.ofNullable(courseMarket).orElse(new CourseMarket()),courseDoc);
            courseDoc.setPrice(Optional.ofNullable(courseMarket.getPrice()).orElse(new BigDecimal(RConst.Num.INT_0)).doubleValue());
            courseDoc.setPriceOld(Optional.ofNullable(courseMarket.getPriceOld()).orElse(new BigDecimal(RConst.Num.INT_0)).doubleValue());
            CourseSummary courseSummary = courseSummaryMapper.selectById(item.getId());
            BeanUtils.copyProperties(Optional.ofNullable(courseSummary).orElse(new CourseSummary()),courseDoc);
            Integer integer = courseCollectMapper.selectCount(new LambdaQueryWrapper<CourseCollect>()
                    .eq(CourseCollect::getCourseId, item.getId()));
            courseDoc.setCollectCount(integer);
            docs.add(courseDoc);
        });
        return docs;
    }
    private void buildCourse(CourseAddDto course, JSONObject currentLogin) {
        course.getCourse().setStatus(RConst.Num.INT_0);
        Integer loginId = (Integer) currentLogin.get("id");//获取的就是当前登录人的id
        Object username = currentLogin.get("username");//获取的就是当前登录人的id
        course.getCourse().setLoginId(loginId.longValue());
        course.getCourse().setLoginUserName(username.toString());
        course.getCourse().setChapterCount(RConst.Num.INT_0);
        //查询老师
        List<Long> teacharIds = course.getTeacharIds();
        List<Teacher> teachers = teacherMapper.selectBatchIds(teacharIds);
        String collect = teachers.stream().map(Teacher::getName)
                .collect(Collectors.joining(","));
        course.getCourse().setTeacherNames(collect);
    }
    @Transactional
    @Override
    public void updateById(CourseAddDto courseAddDto) {
        //主表
        Course course = courseAddDto.getCourse();
        super.updateById(course);
        CourseDetail courseDetail = courseAddDto.getCourseDetail();
        courseDetail.setId(course.getId());
        courseDetailMapper.updateById(courseDetail);
        CourseMarket courseMarket = courseAddDto.getCourseMarket();
        courseMarket.setId(course.getId());
        courseMarketMapper.updateById(courseMarket);
        //特殊
        courseResourceMapper.delete(new LambdaQueryWrapper<CourseResource>()
                .eq(CourseResource::getCourseId,course.getId()));
        CourseResource courseResource = courseAddDto.getCourseResource();
        courseResource.setCourseId(course.getId());
        courseResourceMapper.insert(courseResource);
        courseMapper.deleteTeacherByCourseId(course.getId());
        courseMapper.saveCourseTeacher(course.getId(),courseAddDto.getTeacharIds());
    }
}
